﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Xml;

using ClassLibrary;
using Core;

namespace TestProject
{
    public partial class ChromosomeTableEdit : Form
    {
        private ChromosomeType chrom_type=null;
        private ChromosomeTable chrom_t;
        private Model model;
        private List<ChromosomeGeneLink> chrom_gene_links = new List<ChromosomeGeneLink>();
        private List<CrossingoverLink> cross_links = new List<CrossingoverLink>();
        public ChromosomeTableEdit(Model m, ChromosomeTable ch)
        {
            InitializeComponent();
            model = m;
            chrom_t = ch;
        }
        private void update()
        {
            chrom_box.Items.Clear();
            chrom_t = new ChromosomeTable(chrom_t.path);
            name_box.Text = chrom_t.name;
            if (chrom_t.table != null)
            {
                foreach (ChromosomeType ch in chrom_t.table)
                {
                    chrom_box.Items.Add(ch.name);
                }
            }
        }
        private void ChromosomeTableEdit_Load(object sender, EventArgs e)
        {
            update();
            foreach (ChromosomeGeneLink link in model.model_chromosome_gene_links.Values)
            {
                if (link.path_to_chromosome_table == chrom_t.path)
                    chrom_gene_links.Add(link);
            }
            foreach (CrossingoverLink link in model.model_crossingover_links.Values)
            {
                if (link.path_to_chromosome_table == chrom_t.path)
                    cross_links.Add(link);
            }
        }

        private void chrom_box_SelectedIndexChanged(object sender, EventArgs e)
        {
            locus_box.Items.Clear();            
            foreach (ChromosomeType ch in chrom_t.table)
            {
                if ((string)chrom_box.SelectedItem == ch.name)
                {
                    chrom_type = ch;
                    break;
                }
            }
            for (int i = 0; i < chrom_type.amount_locuses; i++)
            {
                locus_box.Items.Add(i);
            }
        }

        private void remove_butt_Click(object sender, EventArgs e)
        {
            MyXmlDocument doc = new MyXmlDocument();            
            doc.LoadXml(System.IO.File.ReadAllText(chrom_t.path));
            foreach (XmlNode node in doc.GetElementsByTagName("chromosome"))
            {
                if (node.Attributes[0].Value == chrom_type.id.ToString())
                {
                    node.ParentNode.RemoveChild(node);
                    doc.Decrement(doc.DocumentElement.Attributes[1]);
                    break;
                }
            }
            doc.Save(chrom_t.path);
            foreach (ChromosomeGeneLink link in model.model_chromosome_gene_links.Values)
            {
                if (link.path_to_chromosome_table == chrom_t.path)
                {
                    doc = new MyXmlDocument();
                    doc.LoadXml(System.IO.File.ReadAllText(link.path));
                    foreach (XmlNode node in doc.GetElementsByTagName("chromosome"))
                    {
                        if (node.Attributes[0].Value == chrom_type.id.ToString())
                        {
                            node.ParentNode.RemoveChild(node);
                            doc.Decrement(doc.DocumentElement.Attributes[4]);
                            break;
                        }
                    }
                    doc.Save(link.path);
                }
            }
            foreach (CrossingoverLink link in model.model_crossingover_links.Values)
            {
                if (link.path_to_chromosome_table == chrom_t.path)
                {
                    doc = new MyXmlDocument();
                    doc.LoadXml(System.IO.File.ReadAllText(link.path));
                    foreach (XmlNode node in doc.GetElementsByTagName("chromosome"))
                    {
                        if (node.Attributes[0].Value == chrom_type.id.ToString())
                        {
                            node.ParentNode.RemoveChild(node);
                            doc.Decrement(doc.DocumentElement.Attributes[3]);
                            break;
                        }
                    }
                    doc.Save(link.path);
                }
            }
            update();
            chrom_box.SelectedItem = null;
        }

        private void add_butt_Click(object sender, EventArgs e)
        {
            NewChromosome new_chrom = new NewChromosome(chrom_t,chrom_gene_links,cross_links);
            if (new_chrom.ShowDialog(this) == DialogResult.OK)
                update();
        }

        private void add_butt_locus_Click(object sender, EventArgs e)
        {
            XmlDocument doc = new XmlDocument();
            foreach (ChromosomeGeneLink link in chrom_gene_links)
            {
                    SetChromGeneLink set_link = new SetChromGeneLink(link, chrom_box.SelectedIndex);
                    if (set_link.ShowDialog(this) != DialogResult.OK)
                    {
                        MessageBox.Show("Unable to add locus without a link.\nPlease, try again and create it.");
                        return;
                    }
            }
            doc = new XmlDocument();
            foreach (CrossingoverLink link in model.model_crossingover_links.Values)
            {
                doc.LoadXml(System.IO.File.ReadAllText(link.path));
                foreach (XmlNode node in doc.GetElementsByTagName("chromosome"))
                {
                    if (node.Attributes[0].Value == chrom_type.id.ToString())
                    {
                        node.ChildNodes[0].InnerText += " 100";                        
                        break;
                    }
                }
                doc.Save(link.path);
            }
            doc = new XmlDocument();
            doc.LoadXml(System.IO.File.ReadAllText(chrom_t.path));
            doc.GetElementsByTagName("chromosome")[chrom_box.SelectedIndex].Attributes[2].Value = (Convert.ToInt32(doc.GetElementsByTagName("chromosome")[chrom_box.SelectedIndex].Attributes[2].Value) + 1).ToString();
            doc.Save(chrom_t.path);
            int i = chrom_box.SelectedIndex;
            update();
            chrom_box.SelectedIndex = i;
        }

        private void remove_butt_locus_Click(object sender, EventArgs e)
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(System.IO.File.ReadAllText(chrom_t.path));                        
            foreach (XmlNode node in doc.GetElementsByTagName("chromosome"))
            {
                if (node.Attributes[0].Value == chrom_type.id.ToString())
                {
                    node.Attributes[2].Value = (Convert.ToInt32(node.Attributes[2].Value) - 1).ToString();
                    break;
                }
            }
            doc.Save(chrom_t.path);
            foreach (ChromosomeGeneLink link in model.model_chromosome_gene_links.Values)
            {
                if (link.path_to_chromosome_table == chrom_t.path)
                {
                    doc.LoadXml(System.IO.File.ReadAllText(link.path));
                    foreach (XmlNode node in doc.GetElementsByTagName("chromosome"))
                    {
                        if (node.Attributes[0].Value == chrom_type.id.ToString())
                        {
                            List<string> locuses = node.ChildNodes[0].InnerText.Split(' ').ToList();
                            locuses.RemoveAt((int)locus_box.SelectedItem);
                            node.ChildNodes[0].InnerText = null;
                            foreach (string s in locuses)
                            {
                                node.ChildNodes[0].InnerText += s;
                                if (s != locuses.Last())
                                    node.ChildNodes[0].InnerText += " ";
                            }
                            node.Attributes[1].Value = (Convert.ToInt32(node.Attributes[1].Value) - 1).ToString();
                            break;
                        }
                    }
                    doc.Save(link.path);
                }        
            }
            foreach (CrossingoverLink link in model.model_crossingover_links.Values)
            {
                if (link.path_to_chromosome_table == chrom_t.path)
                {
                    doc.LoadXml(System.IO.File.ReadAllText(link.path));
                    foreach (XmlNode node in doc.GetElementsByTagName("chromosome"))
                    {
                        if (node.Attributes[0].Value == chrom_type.id.ToString())
                        {
                            List<string> locuses = node.ChildNodes[0].InnerText.Split(' ').ToList();
                            locuses.RemoveAt((int)locus_box.SelectedItem);
                            node.ChildNodes[0].InnerText = null;
                            foreach (string s in locuses)
                            {
                                node.ChildNodes[0].InnerText += s;
                                if (s != locuses.Last())
                                    node.ChildNodes[0].InnerText += " ";
                            }                            
                            break;
                        }
                    }
                    doc.Save(link.path);
                }
            }
            int i = chrom_box.SelectedIndex;
            update();
            chrom_box.SelectedIndex = i;
            locus_box.SelectedItem = null;
        }

        private void ok_butt_Click(object sender, EventArgs e)
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(System.IO.File.ReadAllText(chrom_t.path));
            doc.DocumentElement.Attributes[0].Value = name_box.Text;
            doc.Save(chrom_t.path);
            this.Close();
        }

        private void ren_butt_Click(object sender, EventArgs e)
        {
            if (chrom_box.SelectedItem != null)
            {
                XmlDocument doc = new XmlDocument();
                doc.LoadXml(System.IO.File.ReadAllText(chrom_t.path));
                foreach (XmlNode node in doc.GetElementsByTagName("chromosome"))
                {
                    if (node.Attributes[1].Value == (string)chrom_box.SelectedItem)
                    {
                    Rename:
                        RenameForm renf = new RenameForm();
                        if (renf.ShowDialog() == DialogResult.OK)
                        {
                            foreach (XmlNode n in doc.GetElementsByTagName("chromosome"))
                            {
                                if ((n.Attributes[1].Value == Data.new_name) && (node.Attributes[1].Value != Data.new_name))
                                {
                                    MessageBox.Show("A chromosome with this name already exists. Please, choose another name.");
                                    goto Rename;
                                }
                            }
                            node.Attributes[1].Value = Data.new_name;
                        }
                        break;
                    }
                }
                doc.Save(chrom_t.path);
                update();
            }
        }
    }
}
